//
//  JQWeChatPayService.m
//  JQWeChatPayService
//
//  Created by JQZ on 2018/1/20.
//  Copyright © 2018年 JQZ. All rights reserved.
//

#import "JQWeChatPayService.h"

#ifdef DEBUG
#define DLog(fmt, ...) NSLog(fmt, ##__VA_ARGS__);
#else
#define DLog(...)
#endif

// 字符串
#define NoNilString(str) ((str && str.length != 0) ? str : @"")
// 没添加 URL Types
#define TIP_URLTYPE @"请先在Info.plist 添加 URL Type"
// 添加了 URL Types 但信息不全
#define TIP_URLTYPE_SCHEME(name) [NSString stringWithFormat:@"请先在Info.plist 的 URL Type 添加 %@ 对应的 URL Scheme",name]

@interface JQWeChatPayService ()<WXApiDelegate>

@property (nonatomic, assign) BOOL sendPayReq;
@property (nonatomic, strong) NSMutableDictionary *appSchemeDict; // appScheme
@property (nonatomic, strong) JQWeChatPayServiceCompletionBlock completionBlock;    // 支付结果回调

@end

@implementation JQWeChatPayService

JQ_EXPORT_SERVICE(JQWeChatPayService)

#pragma mark - #JQWeChatPayService init
- (id)init {
    if (self = [super init]){
        self.sendPayReq = NO;
    }
    return self;
}

#pragma mark - #UIApplicationDelegate
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
    
    // 微信支付初始化
    DLog(@"JQWeChatPayService初始化");
    [self initWechat:launchOptions];
    
    return YES;
}

- (void)applicationDidBecomeActive:(UIApplication *)application {
    if (self.sendPayReq) {
        NSError *error = [self errorWithCode:WXErrCodeUserCancel message:NSLocalizedString(@"Operation is cancel", @"操作取消")];
        self.completionBlock?self.completionBlock(nil,error):nil;
        self.sendPayReq = NO;
    }
}

// 支持所有iOS系统
- (BOOL)application:(UIApplication *)application openURL:(NSURL *)url sourceApplication:(NSString *)sourceApplication annotation:(id)annotation
{
    return [self handleOpenURL:url];
}

// 仅支持iOS9以上系统，iOS8及以下系统不会回调
- (BOOL)application:(UIApplication *)app openURL:(NSURL *)url options:(NSDictionary<UIApplicationOpenURLOptionsKey, id> *)options
{
    return [self handleOpenURL:url];
}

// 支持目前所有iOS系统
- (BOOL)application:(UIApplication *)application handleOpenURL:(NSURL *)url
{
    return [self handleOpenURL:url];
}

- (BOOL)handleOpenURL:(NSURL *)url
{
    BOOL result = [WXApi handleOpenURL:url delegate:self];
    if (!result) {
        // ...
    }
    return result;
}

#pragma mark - #WXApiDelegate
- (void)onResp:(BaseResp *)resp {
    // 微信支付结果
    if ([resp isKindOfClass:[PayResp class]]){
        DLog(@"resp = %@", resp);
        self.sendPayReq = NO;
        PayResp *payResp = (PayResp *)resp;
        if (resp.errCode == WXSuccess){
            self.completionBlock?self.completionBlock(payResp.returnKey,nil):nil;
        }
        else {
            NSError *error = [self errorWithCode:resp.errCode message:resp.errStr];
            self.completionBlock?self.completionBlock(nil,error):nil;
        }
    }
}

#pragma mark - #Public methods
// 发起支付
- (void)payOrder:(PayReq *)req callback:(JQWeChatPayServiceCompletionBlock)completionBlock {
    // 发起微信支付请求
    if ([req isKindOfClass:[PayReq class]]) {
        NSAssert(self.appSchemeDict[WECHAT_URL_NAME], TIP_URLTYPE_SCHEME(WECHAT_URL_NAME));
        self.completionBlock = completionBlock;
        self.sendPayReq = YES;
        [WXApi sendReq:(PayReq *)req];
    }
}

#pragma mark - #自定义关于个推的内容
- (void)initWechat:(NSDictionary *)launchOptions {
    NSString *path = [[NSBundle mainBundle] pathForResource:@"Info" ofType:@"plist"];
    NSDictionary *dict = [NSDictionary dictionaryWithContentsOfFile:path];
    NSArray *urlTypes = dict[@"CFBundleURLTypes"];
    NSAssert(urlTypes, TIP_URLTYPE);
    for (NSDictionary *urlTypeDict in urlTypes) {
        NSString *urlName = urlTypeDict[@"CFBundleURLName"];
        NSArray *urlSchemes = urlTypeDict[@"CFBundleURLSchemes"];
        NSAssert(urlSchemes.count, TIP_URLTYPE_SCHEME(urlName));
        // 一般对应只有一个
        NSString *urlScheme = urlSchemes.lastObject;
        if ([urlName isEqualToString:WECHAT_URL_NAME]) {
            [self.appSchemeDict setValue:urlScheme forKey:WECHAT_URL_NAME];
            // 注册微信
            [WXApi registerApp:urlScheme];
        }
    }
}

#pragma mark - #生成错误信息对象
- (NSError *)errorWithCode:(NSInteger)code message:(NSString *)message {
    NSDictionary* userInfo = [NSDictionary dictionaryWithObject:NoNilString(message) forKey:NSLocalizedDescriptionKey];
    NSError *error = [NSError errorWithDomain:NSStringFromClass(self.class) code:code userInfo:userInfo];
    return error;
}

#pragma mark - #Getter
- (NSMutableDictionary *)appSchemeDict {
    if (!_appSchemeDict){
        _appSchemeDict = [NSMutableDictionary dictionary];
    }
    return _appSchemeDict;
}

@end
